package com.itheima.user.aspect;

// src/main/java/com/example/aspect/LogAspect.java
import com.alibaba.fastjson2.JSON;
import com.itheima.commonmodule.annotation.LogAsync;
import com.itheima.user.entity.SysLogEntity;
import com.itheima.user.entity.UserEntity;
import com.itheima.user.mapper.SysLogMapper;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.scheduling.annotation.Async;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.Date;

@Aspect
@Component
@Slf4j
public class LogAspect {
    @Autowired
    private SysLogMapper sysLogMapper;

    @Autowired
    private HttpServletRequest request;

    // 定义切点：标注@LogAsync的方法
    @Pointcut("@annotation(com.itheima.commonmodule.annotation.LogAsync)")
    public void logPointcut() {}

    // 环绕通知实现日志记录
    @Around("logPointcut()")
    public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        LogAsync logAnnotation = signature.getMethod().getAnnotation(LogAsync.class);

        // 记录方法开始执行时间
        long startTime = System.currentTimeMillis();
        Object result = null;
        Throwable throwable = null;

        try {
            // 执行目标方法
            result = joinPoint.proceed();
            return result;
        } catch (Throwable t) {
            throwable = t;
            throw t; // 重新抛出异常
        } finally {
            // 异步记录日志（不会阻塞主线程）
            asyncRecordLog(joinPoint, logAnnotation, startTime, result, throwable);
        }
    }

    // 异步日志记录方法
    @Async
    public void asyncRecordLog(ProceedingJoinPoint joinPoint,
                               LogAsync logAnnotation,
                               long startTime,
                               Object result,
                               Throwable throwable) {
        long executionTime = System.currentTimeMillis() - startTime;
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        Object[] args = joinPoint.getArgs();

        // 构建日志内容
        StringBuilder logContent = new StringBuilder();
        logContent.append("【").append(logAnnotation.value()).append("】")
                .append(" 执行时间: ").append(executionTime).append("ms | ")
                .append("类: ").append(className)
                .append(" | 方法: ").append(methodName);

        if (logAnnotation.recordParams()) {
            logContent.append(" | 参数: ");
            for (Object arg : args) {
                logContent.append(arg).append(", ");
            }
            if (args.length > 0) {
                logContent.delete(logContent.length() - 2, logContent.length());
            }
        }

        if (throwable != null) {
            logContent.append(" | 异常: ").append(throwable.getMessage());
        }

        // 创建日志实体
        SysLogEntity sysLogEntity = new SysLogEntity();
        sysLogEntity.setAction(logAnnotation.value());
        sysLogEntity.setIp(getClientIp());
        sysLogEntity.setCreatedTime(new Date());
        sysLogEntity.setDetail(JSON.toJSONString(logContent)); // 修复：保存字符串内容而非对象
        sysLogEntity.setUserId(1L);
        // 获取当前用户ID
//        Long userId = getCurrentUserId();
//        if (userId != null) {
//
//        }

        try {
            sysLogMapper.insert(sysLogEntity);
            log.info(logContent.toString());
        } catch (Exception e) {
            log.error("保存日志到数据库失败: ", e);
        }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIp() {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip)) {
            // 多个IP时取第一个
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }

    /**
     * 获取当前用户ID
     */
    private Long getCurrentUserId() {
        // 从请求头中获取token
        String token = request.getHeader("Authorization");
        if (StringUtils.hasText(token) && token.startsWith("Bearer ")) {
            token = token.substring(7);
            try {
                // 解析JWT token获取用户ID
                // 这里需要根据你的JWT工具类实现来调整
                // 假设JwtUtil中有一个方法可以解析用户ID
                // return JwtUtil.getUserIdFromToken(token);
                return null; // 根据实际情况实现
            } catch (Exception e) {
                log.warn("解析用户token失败: ", e);
                return null;
            }
        }
        return null;
    }
}